package com.hxl.tech.gateway.auth.dao;


import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.hxl.tech.gateway.auth.context.ContextHolder;
import com.hxl.tech.gateway.auth.dto.UserInfo;
import com.hxl.tech.gateway.auth.dto.application.ApplicationFindDTO;
import com.hxl.tech.gateway.auth.model.Application;
import com.hxl.tech.gateway.auth.model.QApplication;
import com.hxl.tech.gateway.auth.util.QueryDslOrderUtil;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@Repository
public class ApplicationDao {

    @Resource
    private JPAQueryFactory jpaQueryFactory;

    private QApplication qApplication = QApplication.application;

    public List<Application> find(ApplicationFindDTO findDTO, Boolean page) {

        JPAQuery<Application> query = jpaQueryFactory.select(qApplication).from(qApplication);
        query.where(booleanBuilder(findDTO));

        if (Objects.nonNull(findDTO.getProperty()) && Objects.nonNull(findDTO.getDirection())) {
            OrderSpecifier orderSpecifier = QueryDslOrderUtil.orderByField(qApplication, findDTO.getDirection(), findDTO.getProperty());
            query.orderBy(orderSpecifier);
        } else {
            query.orderBy(qApplication.createTime.desc());
        }

        return BooleanUtil.isTrue(page) ? query.limit(findDTO.limit()).offset(findDTO.offset()).fetch() : query.fetch();
    }

    public Long count(ApplicationFindDTO findDTO) {

        JPAQuery<String> query = jpaQueryFactory.select(qApplication.appId).from(qApplication);
        query.where(booleanBuilder(findDTO));
        return Long.valueOf(query.fetch().size());
    }

    public BooleanBuilder booleanBuilder(ApplicationFindDTO findDTO) {

        UserInfo userInfo = ContextHolder.getUserInfo();
        BooleanBuilder builder = new BooleanBuilder();
        if (StringUtils.isNotEmpty(findDTO.getUserId())) {
            builder.and(qApplication.userId.eq(findDTO.getUserId()));
        }

        if(!userInfo.getIsAdmin()) {
            builder.and(qApplication.userId.eq(userInfo.getUserId()));
        }

        if (StrUtil.isNotBlank(findDTO.getAppId())) {
            builder.and(qApplication.appId.like("%" + findDTO.getAppId() + "%"));
        }
        if (StrUtil.isNotBlank(findDTO.getAppName())) {
            builder.and(qApplication.appName.like("%" + findDTO.getAppName() + "%"));
        }

        return builder;
    }


    public List<Application> findAll() {

        JPAQuery<Application> query = jpaQueryFactory.select(qApplication).from(qApplication);

        return query.fetch();
    }

    public List<Application> listByUserIdAndAppName(String userId, String appName) {

        JPAQuery<Application> query = jpaQueryFactory.select(qApplication)
                .from(qApplication)
                .where(qApplication.userId.eq(userId).and(qApplication.appName.eq(appName)));
        return query.fetch();
    }

    public Application read(String appId) {

        JPAQuery<Application> query = jpaQueryFactory.select(qApplication)
                .from(qApplication)
                .where(qApplication.appId.eq(appId));
        return query.fetchOne();
    }
}
